package main

import (
	"encoding/json"
	"fmt"
)

//结构体是值类型,序列话时该值首字母大写才能被其他包访问调用，小写的不展示
type cat struct {
	Age     int `json:"age"`
	High    int
	friends *string
}

func main() {
	type dog struct {
		Age, high int
	}
	var c1 cat
	c1.Age = 5
	//引用类型为nil且为基础数据类型时需要先new再赋值，或者直接赋值一个现成的，复杂数据类型是make
	c3 := "c3Cat"
	//c1.friends = new(string)
	//*c1.friends = "c2"
	c1.friends = &c3
	fmt.Println(c1, c1.Age, *c1.friends, c1.friends, &c1.friends, c1.High)
	d1 := dog{}
	//有引用类型也可以用:=声明再赋值一个空结构体,和var一样
	c2 := cat{}
	fmt.Println(d1, c2, d1.Age, d1.high)

	//当结构体以指针形式传给其他函数时，(*ptr).x == ptr.x,开发者在底层做了优化一种语法糖
	test1(&c1)

	//fmt.Println(*&c3),这个不会报错，正常运行，但是会报警

	var c4 *cat = &c1
	fmt.Println(c4)
	fmt.Println(c4.Age) // == fmt.Println((*c4).Age) ,*c4必须用()括起来，不然报错，因为.的优先级高于*

	//序列化和反序列化
	jsonstr, err := json.Marshal(c1)
	if err != nil {
		fmt.Println("json处理错误:", err)
	}
	fmt.Println(jsonstr, string(jsonstr))
	fmt.Printf("%c%c%c%c%c\n", 123, 34, 97, 34, 125)

	//结构体和map一样直赋值时最后都需要有逗号
	c5 := cat{
		Age:     15,
		High:    18,
		friends: &c3,
	}
	fmt.Println(c5)

}

func test1(c *cat) {
	fmt.Println(c.Age, c.friends)
}
